package ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.entrega2;
import java.text.ParseException;

import junit.framework.Assert;

import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
import org.uqbar.commons.utils.ApplicationContext;

import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.capturas.Captura;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.capturas.Image;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.capturas.TipoInfraccion;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.capturas.Zona;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.categorias.Categoria;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.categorias.Evasor;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.categorias.InfractorFrecuente;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.categorias.Inhabilitado;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.externos.VerificadorDePagos;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.homes.AdministradorCategorias;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.homes.AdministradorVehiculos;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.mockObjects.*;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.notificaciones.NotificacionMail;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.notificaciones.NotificacionSMS;
import ar.edu.utn.frba.tadp.tp.grupo4.fotomultas.vehiculos.Vehiculo;


public class Punto1TestCase {
	
	
	//Los nombre de las capturas en este caso no importan porque son todas iguales.
	//Hacemos varias instancias, para que las agregue en un Set
	public Captura captura1;
	public Captura captura2;
	public Captura captura3;
	public Captura captura4;
	public Captura captura5;
	public Captura captura6;
	public Zona zona = new Zona("Zona Roja", "12345");
	public TipoInfraccion tipoInfraccion = new TipoInfraccion("Mal Estacionamiento", 20, 300);
	
	//public AdministradorCategorias adCat = new AdministradorCategorias();

	public AdministradorCategorias adCat;
	
	public Categoria evasor = new Evasor();
	public Categoria inhabilitado = new Inhabilitado();
	public Categoria iFrecuente = new InfractorFrecuente();
	public Vehiculo vehiculo;
	public AdministradorVehiculos adVehiculos;
	
	//public VerificadorPagos verificadorPagos = new VerificadorPagos();
	public VerificadorPagos verificadorPagos;
	
	@Before
	public void setUp(){
		
		ApplicationContext.getInstance().configureSingleton(VerificadorDePagos.class, new VerificadorPagos());
		ApplicationContext.getInstance().configureSingleton(AdministradorCategorias.class, new AdministradorCategorias());
		ApplicationContext.getInstance().configureSingleton(AdministradorVehiculos.class, new AdministradorVehiculos());
		
		adCat = ApplicationContext.getInstance().getSingleton(AdministradorCategorias.class);
		adVehiculos = ApplicationContext.getInstance().getSingleton(AdministradorVehiculos.class);
		verificadorPagos = ApplicationContext.getInstance().getSingleton(VerificadorDePagos.class);
		
		DateTime unaFechaCualquiera = new DateTime(2011, 1, 1, 0, 0, 0, 0);
		
		captura1 = new Captura(zona, tipoInfraccion, new Image(), unaFechaCualquiera);
		captura2 = new Captura(zona, tipoInfraccion, new Image(), unaFechaCualquiera);
		captura3 = new Captura(zona, tipoInfraccion, new Image(), unaFechaCualquiera);
		captura4 = new Captura(zona, tipoInfraccion, new Image(), unaFechaCualquiera);
		captura5 = new Captura(zona, tipoInfraccion, new Image(), unaFechaCualquiera);
		captura6 = new Captura(zona, tipoInfraccion, new Image(), unaFechaCualquiera);
		
		adCat.addCategoria(evasor);
		adCat.addCategoria(inhabilitado);
		adCat.addCategoria(iFrecuente);
		
		//vehiculo = new Vehiculo("ASD 123", adCat, verificadorPagos);
		vehiculo = new Vehiculo("ASD 123");
		
		
		NotificacionSMS notificacionSMS = new NotificacionSMS(new SMSSender());
		
		MailSender unMailSender = new MailSender();
		NotificacionMail notificacionMail = new NotificacionMail(unMailSender);
		notificacionMail.setFrom("sistema-fotomultas@tadp.com.ar");
		notificacionMail.setDireccion("teponeslagorra@policiafederal.gob.ar");
		
		tipoInfraccion.addNotificacion(notificacionSMS);
		
		evasor.setNotificacion(notificacionMail);
		inhabilitado.setNotificacion(notificacionMail);
		
		adVehiculos = new AdministradorVehiculos();
		adVehiculos.addVehiculo(vehiculo);
	}
	
	
	@Test
	public void verificarDesAsignacionEvasorPorMultaPagada(){
		
		
		vehiculo.addCaptura(captura1);
		vehiculo.addCaptura(captura2);
		vehiculo.addCaptura(captura3);
		vehiculo.addCaptura(captura4);
		
		Assert.assertTrue(vehiculo.estaEnLaCategoria(evasor));
		
		// Al verificar los pagos, el mock va a devolver la primer multa como " impaga"
		// y el resto como pagadas.
		adVehiculos.verificarCategorias();
		
		Assert.assertFalse(vehiculo.estaEnLaCategoria(evasor));
		
	}
	
	@Test
	public void verificarDesAsignacionEvasorPorMultaVencida() throws ParseException{
		
		vehiculo.addCaptura(captura1);
		vehiculo.addCaptura(captura2);
		vehiculo.addCaptura(captura3);
		vehiculo.addCaptura(captura4);
		
		Assert.assertTrue(vehiculo.estaEnLaCategoria(evasor));
		
		DateTime fechaVencida = new DateTime(2000, 1, 1, 0, 0, 0, 0);
		
		// la captura estar�a vencida y no deber�a sumar
		captura4.setFecha(fechaVencida);
		
		adVehiculos.verificarCategorias();
		Assert.assertFalse(vehiculo.estaEnLaCategoria(evasor));
		
	}
	
	@Test
	public void verificarDesAsignacionFrecuente() throws ParseException{
		
		vehiculo.addCaptura(captura1);
		vehiculo.addCaptura(captura2);
		vehiculo.addCaptura(captura3);
		vehiculo.addCaptura(captura4);
		vehiculo.addCaptura(captura5);
		vehiculo.addCaptura(captura6);
		
		Assert.assertTrue(vehiculo.estaEnLaCategoria(iFrecuente));
		
		DateTime fechaMasDe6Meses = new DateTime(2010, 6, 1, 0, 0, 0, 0);
		
		// la ultima captura tendria mas de 6 meses, por lo que no tendria
		// que pertenecer mas a la categoria
		vehiculo.getCapturas().get(5).setFecha(fechaMasDe6Meses);
		//captura6.setFecha(fechaMasDe6Meses);
		
		adVehiculos.verificarCategorias();
		Assert.assertFalse(vehiculo.estaEnLaCategoria(iFrecuente));
		
	}
	
	@Test
	public void verificarDesAsignacionInhabilitadoPorMultasPagadas() throws ParseException{
		
		
		vehiculo.addCaptura(captura1);
		vehiculo.addCaptura(captura2);
		vehiculo.addCaptura(captura3);
		vehiculo.addCaptura(captura4);
		vehiculo.addCaptura(captura5);
		
		Assert.assertTrue(vehiculo.estaEnLaCategoria(inhabilitado));
		
		
		// Para que verifique que no se las desasigne si la �ltima multa tiene m�s de 
		// 6 meses aunque tenga todo pago.
		DateTime fechaMenosDe6Meses = new DateTime(2011, 6, 1, 0, 0, 0, 0);
		
		//captura5.setFecha(fechaMenosDe6Meses);
		vehiculo.getCapturas().get(4).setFecha(fechaMenosDe6Meses);
		// Hack loco para hacer que el verificador de pagos devuelva todas las multas como pagadas
		verificadorPagos.setFlag(true);
		
		Assert.assertTrue(vehiculo.estaEnLaCategoria(inhabilitado));
		
		// Al verificar los pagos, el mock va a devolver la primer multa como "pagada"
		// y el resto como impagas.
		
		DateTime fechaMasDe6Meses = new DateTime(2010, 6, 1, 0, 0, 0, 0);
		//captura5.setFecha(fechaMasDe6Meses);
		vehiculo.getCapturas().get(4).setFecha(fechaMasDe6Meses);
		adVehiculos.verificarCategorias();
		
		Assert.assertFalse(vehiculo.estaEnLaCategoria(inhabilitado));
		
	}

}